/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package xmluebung2;

import java.awt.Graphics;
import java.awt.Polygon;
import javax.swing.BorderFactory;
import javax.swing.JPanel;

/**
 * AbstractPanel, superclass for all required panels. Extends JPanel.
 * 
 * @author Adrian Cieluch
 */
public abstract class AbstractPanel extends JPanel {
    private double scale = 0;
    private double distanceX = 0, distanceY = 0;
    private double minX = 0, maxX = this.getWidth();
    private Polygon poly = new Polygon();
    private ColorScheme colorScheme;
    private int width;
    private int height;
    
    /**
     * Abstract function for the mathmatical function
     * 
     * @param x x value for the function.
     * @return calculated y value
     */
    public abstract double calculateYValue(double x);
    
    /**
     * Constructor, sets width, height and border.
     * 
     * @param w width
     * @param h height
     */
    public AbstractPanel(int w, int h) {
        this.width = w;
        this.height = h;
        
        this.setBorder(BorderFactory.createRaisedBevelBorder());
    }
    
    /**
     * Creates the polygon for the mathmatical function.
     */
    public void setFunctionValues() {
        for(double i = this.minX; i <= this.maxX; i += 0.1) {
            double x = i * distanceX + this.width/2;
            double y = this.calculateYValue(i) * distanceY + this.height/2;
            
            this.poly.addPoint((int)x, (int)y);
        }
    }
    
    /**
     * Sets the minimum and maximum values for the definition area.
     * 
     * @param x value for the definition area.
     */
    public void setDefinitionValues(int x) {  
        this.scale = x/10.0;
        this.minX = -x;
        this.maxX = x;
        this.distanceX = (double)this.width / (double)(2*x);
        this.distanceY = (double)this.height / (double)(2*x);
    }
    
    /**
     * Sets the colorScheme.
     * 
     * @param s Colorscheme
     */
    public void setColorScheme(ColorScheme s) {
        this.colorScheme = s;
    }
    
    /**
     * Draws the background.
     * 
     * @param g Graphics object
     */
    public void drawBackground(Graphics g) {
        g.setColor(colorScheme.background);
        g.fillRect(0, 0, this.width, this.height);
    }
    
    /**
     * Draws the coordinatesystem.
     * 
     * @param g Graphics object
     */
    public void drawCoordinateSystem(Graphics g) {
        g.setColor(colorScheme.coordinateSystem);
        
        //Horizontal
        g.drawLine(0, this.height/2, this.width, this.height/2);
        
        for(int i = (int)this.minX; i <= (int)this.maxX; i++) {
            double x = i * distanceX + this.width/2;
            g.drawLine((int)x, this.height/2-5, (int)x, this.height/2+5);
        }
        
        //Vertical
        g.drawLine(this.width/2, 0, this.width/2, this.height);
        
        for(int i = (int)this.minX; i <= (int)this.maxX; i++) {
            double y = i * distanceY + this.height/2;
            g.drawLine(this.width/2-5, (int)y, this.width/2+5, (int)y);
        }
    }
    
    /**
     * Draws the function.
     * 
     * @param g Graphics object
     */
    public void drawFunction(Graphics g) {
        g.setColor(colorScheme.function);
        g.drawPolyline(poly.xpoints, poly.ypoints, poly.npoints);
    }
    
    /**
     * Paints all the different components on the panel.
     * 
     * @param g Graphics object
     */
    public void paintComponent(Graphics g) {
        this.drawBackground(g);
        this.drawCoordinateSystem(g);
        this.drawFunction(g);
    }
}